package edu.scnu.fans.fingertip.user.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import edu.scnu.fans.fingertip.common.api.IdRequest;
import edu.scnu.fans.fingertip.common.web.BusinessException;
import edu.scnu.fans.fingertip.user.input.UserAddressDto;
import edu.scnu.fans.fingertip.user.mapper.UserAddressMapper;
import edu.scnu.fans.fingertip.user.model.UserAddress;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
public class UserAddressService {

    @Resource
    private UserAddressMapper userAddressMapper;

    /**
     * 用户收货地址列表
     */
    public List<UserAddressDto> list(Long userId) {
        // 查询用户全部的收货地址，按是否默认和创建时间倒序排序
        return userAddressMapper.selectList(new LambdaQueryWrapper<UserAddress>()
                        .eq(UserAddress::getUserId, userId)
                        .orderByDesc(UserAddress::getDefaultAddress)
                        .orderByDesc(UserAddress::getCreated))
                .stream()
                .map(UserAddress::transferToOutput)
                .collect(Collectors.toList());
    }

    /**
     * 根据id找收货地址
     */
    public UserAddressDto findAddressById(Long userId, IdRequest input) {
        return Optional.ofNullable(userAddressMapper.selectOne(new LambdaQueryWrapper<UserAddress>()
                        .eq(UserAddress::getId, input.getId())
                        .eq(UserAddress::getUserId, userId)))
                .map(UserAddress::transferToOutput)
                .orElseThrow(() -> new BusinessException("收货地址不存在"));
    }

    /**
     * 添加收货地址
     */
    @Transactional
    public void add(Long userId, UserAddressDto input) {
        Integer existCount = userAddressMapper.selectCount(new LambdaQueryWrapper<UserAddress>()
                .eq(UserAddress::getUserId, userId));

        int maxAddressCount = 20;

        if (existCount > maxAddressCount) {
            throw new BusinessException("最多" + maxAddressCount + "个地址");
        }

        UserAddress address = new UserAddress(userId);
        address.update(input);

        // 如果是第一次添加，则设置为默认地址
        if (existCount == 0) {
            address.setDefaultAddress(true);
        }

        // 保存入库
        userAddressMapper.insert(address);
    }

    /**
     * 更新收货地址
     */
    @Transactional
    public void update(Long userId, UserAddressDto input) {
        UserAddress address = Optional.ofNullable(userAddressMapper.selectOne(
                new LambdaQueryWrapper<UserAddress>()
                        .eq(UserAddress::getId, input.getId())
                        .eq(UserAddress::getUserId, userId)))
                .orElseThrow(() -> new BusinessException("地址不存在"));

        // 更新数据
        address.update(input);
        // 更新入库
        userAddressMapper.updateById(address);
    }

    /**
     * 删除收货地址
     */
    @Transactional
    public void delete(Long userId, IdRequest input) {
        UserAddress address = userAddressMapper.selectOne(new LambdaQueryWrapper<UserAddress>()
                .eq(UserAddress::getId, input.getId())
                .eq(UserAddress::getUserId, userId));

        // 如果存在则删除，不存在则忽略
        if (address == null) {
            return;
        }

        if (address.getDefaultAddress()) {
            throw new BusinessException("不能删除默认地址");
        }

        // 逻辑删除
        userAddressMapper.deleteById(input.getId());
    }

    /**
     * 设置默认收货地址
     */
    @Transactional
    public void setDefaultAddress(Long userId, IdRequest input) {
        // 新的收货地址
        UserAddress newDefaultAddress = Optional.ofNullable(userAddressMapper.selectOne(new LambdaQueryWrapper<UserAddress>()
                        .eq(UserAddress::getId, input.getId())
                        .eq(UserAddress::getUserId, userId)))
                .orElseThrow(() -> new BusinessException("收货地址不存在"));

        // 将原来的默认地址更新为非默认
        userAddressMapper.setUnDefaultByUserId(userId);

        // 设置新收货地址为默认地址，更新入库
        newDefaultAddress.setDefaultAddress(true);
        userAddressMapper.updateById(newDefaultAddress);
    }

}
